/***********************************************************
 *  File_Name  : XJThreadManager.h
 *  File_Path   :
 *  File_Encode : UTF8
 *  Description : 线程管理类
 *
 *  OS : Linux, UNIX
 *  LastVersion  : 20130723
 *
 *  Author      : LiXiujie(李秀杰)
 *  Date        : 2013-7-23
 *  Version     : 20130723
 *  Description :
 *
 *  Edit Author :
 *  Edit Date   :
 *  Version     :
 *  Description :
 *
 ***********************************************************/
#ifndef XJTHREADMANAGER_H_
#define XJTHREADMANAGER_H_
#include <pthread.h>
#include <vector>
namespace XJUtilClass
{

	

	class XJThreadManager;


	class XJThreadManager
	{
	public:
		XJThreadManager();
		virtual ~XJThreadManager();

	public:
		// 线程运行状态
		enum XJThreadRunState
		{
			R_S_BEGIN = 0,	// 线程开始
			R_S_RUNING = 1, // 线程循环中
			R_S_END = 2,	// 线程结束
		};
		/* 线程内部每一个循环方法  , 返回非0，线程退出 */
		typedef int (*XJ_THR_FUNC)(XJThreadRunState, void *);

		// 线程信息
		typedef struct _XJThreadInfo
		{
			pthread_t t_id;
			int state;		 // 状态
			int group;		 // 分组
			int join;		 // 分离
			int exit;		 // 可以退出
			XJ_THR_FUNC fun; // 运行函数
			void *arg;		 // 函数参数
			int opt;		 // 操作
			pthread_t t_opt; // 操作线程
			void *pData;	 // 内部数据
			long create_time; // 创建时间
			long begin_time;  // 开始时间
			long end_time;	 // 结束时间
			int exit_reason; // 线程退出原因
			XJThreadManager *parent;
		} XJThreadInfo;
		// 线程属性
		enum XJThreadAttr
		{
			XJ_THR_A_EXIT_ENABLE = 0x00000001,	  // 允许取消这个线程。
			XJ_THR_A_DETACHED = 0x00000002,		  // 创建异步线程。线程的退出状态对于其他任何线程不可用。当线程终止时，操作系统回收线程资源。
			XJ_THR_A_JOINABLE = 0x00000004,		  // 允许新线程的退出状态对于其他线程可用。这也是 ACE 创建的线程的默认属性。当这种线程终止时，操作系统不回收线程资源，直到其他线程联结它为止。
			XJ_THR_A_NEW_LWP = 0x00000008,		  // 创建显式的内核级线程（而不是用户级线程）。
			XJ_THR_A_SUSPENDED = 0x00000010,	  // 创建处于暂停状态的新线程。
			XJ_THR_A_INHERIT_SCHED = 0x00000020,  // 表示新现成将继承创建线程的调度策略和参数
			XJ_THR_A_EXPLICIT_SCHED = 0x00000040, // 表示使用在schedpolicy和schedparam属性中显式设置的调度策略和参数
			XJ_THR_A_EXIT_DISABLE = 0x00000100,	  // 不允许取消这个线程。
		};
		// 线程状态
		enum XJThreadState
		{
			/// Uninitialized. 未创建
			XJ_THR_S_IDLE = 0x00000000,
			/// Created but not yet running.创建了但没有运行
			XJ_THR_S_SPAWNED = 0x00000001,
			/// Thread is active (naturally, we don't know if it's actually
			/// *running* because we aren't the scheduler...).运行的
			XJ_THR_S_RUNNING = 0x00000002,
			/// Thread is suspended.暂停的
			XJ_THR_S_SUSPENDED = 0x00000004,
			///
			XJ_THR_S_EXITED = 0x00000008,
		};

		/*方法：单实例
		 * */
		static XJThreadManager *instance();

		/*方法：单实例
		 * */
		static void close_singleton(void);
		/*方法：创建一个新线程
		 * */
		int spawn(XJ_THR_FUNC func,
				  void *arg = 0,
				  long flags = XJ_THR_A_NEW_LWP | XJ_THR_A_JOINABLE | XJ_THR_A_INHERIT_SCHED,
				  pthread_t *t_id = 0,
				  long priority = 0,
				  int grp_id = 0,
				  size_t stack_size = 0);
		int spawn_n(size_t n,
					XJ_THR_FUNC func,
					void *arg = 0,
					long flags = XJ_THR_A_NEW_LWP | XJ_THR_A_JOINABLE | XJ_THR_A_INHERIT_SCHED,
					pthread_t *t_id = 0,
					long priority = 0,
					int grp_id = 0,
					size_t stack_size = 0);
		/*方法：终止一个线程
		 * */
		int exit_all();
		int exit(pthread_t t_id);
		int exit_group(int group_id);
		int exit_fun(XJ_THR_FUNC func);
		int exit_self();
		/*方法：线程管理器暂停指定的线程
		 * */
		int suspend_all();
		int suspend(pthread_t t_id);
		int suspend_group(int group_id);
		int suspend_fun(XJ_THR_FUNC func);
		int suspend_self();
		/*方法：线程管理器恢复执行前面暂停的线程
		 * */
		int resume_all();
		int resume(pthread_t t_id);
		int resume_group(int group_id);
		int resume_fun(XJ_THR_FUNC func);
		// int resume_self();
		/*方法：线程阻塞，等待子线程退出：
		 * */
		int wait_all(size_t milli);
		int wait(size_t milli, pthread_t t_id);
		int wait_group(size_t milli, int group_id);
		int wait_fun(size_t milli, XJ_THR_FUNC func);
		// int wait_self();
		/*方法：获取线程状态
		 * */
		int get_state(pthread_t t_id);
		/*方法：判断线程状态
		 * */
		bool is_state_all(int state);
		bool is_state(pthread_t t_id, int state);
		bool is_state_group(int group_id, int state);
		bool is_state_fun(XJ_THR_FUNC func, int state);
		/*方法：杀死所有进程
		 * */
		int kill_all();
		/*方法：线程内部数据获取
		 * */
		void *get_data_self();
		/*方法：线程内部数据设置
		 * */
		void *set_data_self(void *);

	private:
		enum XJThreadOpt
		{
			XJ_THR_O_EXIT = 1,
			XJ_THR_O_SUSPEND,
			XJ_THR_O_RESUME
		};
		static void *XJ_Thread_Fun(void *pData);
		int spawn_i(size_t n,
					XJ_THR_FUNC func,
					void *arg = 0,
					long flags = XJ_THR_A_NEW_LWP | XJ_THR_A_JOINABLE | XJ_THR_A_INHERIT_SCHED,
					pthread_t *t_id = 0,
					long priority = 0,
					int grp_id = 0,
					size_t stack_size = 0);
		std::vector<XJThreadInfo *> m_veThreadInfos;
		static XJThreadManager *m_pThis;
		static pthread_mutex_t m_ThreadMutex;
	};

} /* namespace XJUtilClass */
#endif /* XJTHREADMANAGER_H_ */
